﻿using System;
using System.Diagnostics;
using System.Reflection;
using System.Web;
using System.Web.UI;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;
using Utils;

namespace SPListNavigation.UpButton
{
    public class Action : SPLinkButton
    {
        private string newFolder = null;
        private bool _error = false;
        private int currentLine = 0;


        /// <summary>
        /// Clear all child controls and add an error message for display.
        /// </summary>
        /// <param name="ex"></param>
        private void HandleException(Exception ex)
        {
            this._error = true;
            Logger.Error("line " + currentLine + ".Current User:" + System.Threading.Thread.CurrentPrincipal.Identity.Name + " ", ex, "OP.SPCustomActions.UpButton");
            this.Page.Controls.Add(new LiteralControl(System.Environment.NewLine));
            this.Page.Controls.Add(new LiteralControl("<!--" + ex.Message + "-->"));
            this.Page.Controls.Add(new LiteralControl("<!--" + ex.StackTrace + "-->"));
            this.Page.Controls.Add(new LiteralControl(System.Environment.NewLine));
        }

        protected override void OnPreRender(EventArgs e)
        {
            //Tracer(" Begin OnPreRender ");
            currentLine = 39;
            if (newFolder != null)
            {
                newFolder = HttpUtility.UrlEncode(newFolder);
                SetViewStateOnListView();
            }
            base.OnPreRender(e);
            //Tracer("End OnPreRender");
        }

        protected void Tracer(string info)
        {
            HttpContext.Current.Response.Write("<!--" + "<TRACE> (line " + currentLine + ")" + info + " </TRACE> " + "-->");
            Logger.Info("<TRACE> " + info + " </TRACE> ", "UpButton");
            Page.Response.Write(System.Environment.NewLine);
            return;
            this.Page.Controls.Add(new LiteralControl("<!--" + "<TRACE> " + info + " </TRACE> " + "-->"));
            this.Page.Controls.Add(new LiteralControl(System.Environment.NewLine));
        }

        protected void Debug(string info)
        {
            HttpContext.Current.Response.Write("<!--" + "<DEBUG> " + info + " </DEBUG> " + "-->");
            Page.Response.Write(System.Environment.NewLine);
            Logger.Info("<DEBUG> " + info + " </DEBUG> ", "UpButton");
            return;
            this.Page.Controls.Add(new LiteralControl("<!--" + "<DEBUG> " + info + " </DEBUG> " + "-->"));
            this.Page.Controls.Add(new LiteralControl(System.Environment.NewLine));
        }

        private void SetViewStateOnListView()
        {
            try
            {
                currentLine = 70;
                Tracer("Begin SetViewStateOnListView ");
                ListViewWebPart lv = this.FindListView(this.Parent);
                currentLine = 73;
                if (lv != null)
                {
                    StateBag vs = (StateBag)GetPrivatePropertyValue(typeof(Control), lv, "ViewState");
                    vs["RootFolder"] = newFolder;
                    Visible = false;
                }
            }
            catch (Exception ex)
            {
                Trace.WriteLine(ex);
                currentLine = 84; Tracer("out line " + currentLine);
                HandleException(ex);
                Tracer("Error in SetViewStateOnListView: " + ex.Message + ";" + ex.StackTrace);
            }
            Tracer("End SetViewStateOnListView ");
        }

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            this.Style.Clear();
            this.Text = "Up Folder";
            this.ImageUrl = SPContext.Current.Site.Url + "/_layouts/images/upfolder.gif";
            this.ToolTip = "Up to parent folder";
            this.CssClass = "CLAFONTAINE";
        }

        protected override void OnLoad(EventArgs e)
        {
            try
            {
                ListViewWebPart lv = FindListView(this.Parent);

                if (lv == null)
                {
                    Visible = false;
                    Tracer("out line 72");
                    return;
                }
                string sOriginalRootFolder = GetOriginalFolder(lv);
                //sOriginalRootFolder = HttpUtility.UrlEncode(sOriginalRootFolder); sOriginalRootFolder = sOriginalRootFolder.Replace("/", "%2");
                currentLine = 117;
                if (string.IsNullOrEmpty(sOriginalRootFolder))
                {
                    Visible = false;
                    Tracer("out line 120");
                    return;
                }
                #region new code
                //code ajouté jeudi 4 fevrier apres midi
                if (SPContext.Current.List.RootFolder.ServerRelativeUrl == sOriginalRootFolder)
                {
                    newFolder = null;
                    Visible = false;
                    return;
                }
                #endregion

                currentLine = 123;
                string sNewRootFolder = sOriginalRootFolder.Substring(0, sOriginalRootFolder.LastIndexOf("/"));

                Tracer(" sOriginalRootFolder=" + sOriginalRootFolder);
                //Tracer(" sOriginalRootFolder.Split('/').Length=" + sOriginalRootFolder.Split('/').Length);

                if (Page.Request["Key"] != null)
                    Tracer(" Page.Request[\"Key\"]=" + Page.Request["Key"]);
                if (lv != null && lv.StorageKey != null)
                    Tracer(" lv.StorageKey.ToString()=" + lv.StorageKey.ToString());

                if (Page.Request["Key"] == lv.StorageKey.ToString() && sOriginalRootFolder.Split('/').Length <= 2)
                {
                    newFolder = sNewRootFolder;
                    currentLine = 141; Tracer("out line " + currentLine);
                    return;
                }
                /*Begin add new code*/
                try
                {
                    string baseRootFolder = SPContext.Current.Web.Url.Replace("http://", "").Replace("https://", "");//Replace(SPContext.Current.Site.Url, "");
                    baseRootFolder = baseRootFolder.Substring(baseRootFolder.IndexOf("/", 0));

                    Debug("BASEROOTFOLDER =" + baseRootFolder);

                    Debug("HttpContext.Current.Request[RootFolder]=" + HttpContext.Current.Request["RootFolder"]);

                    string RootFolderUrlParam = HttpContext.Current.Request["RootFolder"];


                    //RootFolderUrlParam = RootFolderUrlParam.Replace("%2f", "/");
                    if (RootFolderUrlParam.Contains("%2f"))
                        RootFolderUrlParam = HttpUtility.UrlDecode(RootFolderUrlParam);

                    if (baseRootFolder.Equals(RootFolderUrlParam))
                    {
                        this.Visible = false;
                        return;
                    }

                    if (SPContext.Current.List != null)
                    {
                        string abs = HttpContext.Current.Request.Url.AbsoluteUri;
                        string listUrl = SPContext.Current.List.RootFolder.Url;

                        Debug("HttpContext.Current.Request.Url.AbsoluteUri=" + abs);

                        Debug("HttpContext.Current.Request.Url.AbsolutePath=" + HttpContext.Current.Request.Url.AbsolutePath);

                        Debug("SPContext.Current.List.RootFolder.Url=" + SPContext.Current.List.RootFolder.Url);

                        Debug("SPContext.Current.Site.Url=" + SPContext.Current.Site.Url);
                        Debug("SPContext.Current.Web.Url=" + SPContext.Current.Web.Url);


                        if (this.Page.Request["RootFolder"] != null)
                        {
                            if (SPContext.Current.List != null)
                            {
                                Debug("SPContext.Current.List.RootFolder.Url:" + SPContext.Current.List.RootFolder.Url);

                                //Debug("SPContext.Current.ListItemServerRelativeUrl:" + SPContext.Current.ListItemServerRelativeUrl);

                                Debug("SPContext.Current.List.DefaultViewUrl:" + SPContext.Current.List.DefaultViewUrl);

                                if (HttpUtility.UrlDecode(this.Page.Request["RootFolder"]) == SPContext.Current.List.RootFolder.Url)
                                {
                                    currentLine = 168; Tracer("out line " + currentLine);
                                    return;
                                }
                            }
                        }
                    }
                }
                catch (Exception exc)
                {
                    currentLine = 178; Tracer("out line " + currentLine);
                    HandleException(exc);
                }

                try
                {
                    SPList list = null;
                    if (string.IsNullOrEmpty(HttpContext.Current.Request["RootFolder"]) == false)
                    {
                        string strUrl = HttpContext.Current.Request["RootFolder"];
                        if (strUrl.EndsWith("/"))
                            strUrl = strUrl.Remove(strUrl.LastIndexOf("/"));

                        list = SPContext.Current.Web.GetList(strUrl);
                        if (list != null)
                        {
                            this.ImageUrl = SPContext.Current.Site.Url + "/_layouts/images/" + "WP_AREA.GIF";
                            this.Text = "Show Flat View";
                        }
                    }

                }
                catch { }
                /*end add new code*/
                this.OnClientClick = ClientJavascript(lv, sNewRootFolder);
                //this.Visible = true;
                currentLine = 183;
                Text = "Up Folder";
                ImageUrl = "/_layouts/images/upfolder.gif";
                ToolTip = "Up to parent folder";
                currentLine = 187; Tracer("out line " + currentLine);
            }
            catch (Exception ex)
            {
                Trace.WriteLine(ex);
                currentLine = 192; Tracer("out line " + currentLine);
                Tracer("error line:" + currentLine + "." + ex.Message + ";" + ex.StackTrace);
            }
            base.OnLoad(e);
        }

        private string GetOriginalFolder(ListViewWebPart lv)
        {
            string sOriginalRootFolder = (string)GetPrivateFieldValue(lv, "rootFolder");

            if (Page.Request["Key"] == lv.StorageKey.ToString())
                sOriginalRootFolder = Page.Request["RootFolder"];

            Debug("Page.Request[Key]=" + Page.Request["Key"]);

            return sOriginalRootFolder;
        }

        private string ClientJavascript(ListViewWebPart lv, string sNewRootFolder)
        {
            string sCurrentUrl = HttpContext.Current.Request.Url.ToString();

            if (sCurrentUrl.Contains("?"))
                sCurrentUrl = sCurrentUrl.Substring(0, sCurrentUrl.IndexOf("?"));

            string sCTID = (string)GetPrivateFieldValue(lv, "folderCtId");

            string sStart = ((sNewRootFolder == "") ? "?" : SPHttpUtility.EcmaScriptStringLiteralEncode(sCurrentUrl + "?RootFolder=" + sNewRootFolder) + "&");

            sStart = SPHttpUtility.EcmaScriptStringLiteralEncode(sCurrentUrl + "?RootFolder=" + sNewRootFolder) + "&";
           

            string sNavigateUrl = sStart
                                  + "FolderCTID=" + SPHttpUtility.EcmaScriptStringLiteralEncode(sCTID)
                                  + "&View=" + SPHttpUtility.EcmaScriptStringLiteralEncode(lv.ViewGuid)
                                  + "&Key=" + lv.StorageKey.ToString();
            
            //&SortField=Modified&SortDir=Asc
            if (HttpContext.Current.Request.Url.Query.Contains("SortField"))
            {
               sNavigateUrl= "&SortField="+GetParam(HttpContext.Current.Request.Url,"SortField");
            }

            if (HttpContext.Current.Request.Url.Query.Contains("SortDir"))
            {
                sNavigateUrl = "&SortDir=" + GetParam(HttpContext.Current.Request.Url, "SortDir");
            }

            return "javascript:location.replace('" + sNavigateUrl + "');return false";

            //return "javascript:EnterFolder('" + sNavigateUrl + "');return false";
        }

        private static object GetPrivateFieldValue(object obj, string fieldName)
        {
            FieldInfo fi = obj.GetType().GetField(fieldName, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
            return fi.GetValue(obj);
        }

        private static object GetPrivatePropertyValue(Type t, object obj, string fieldName)
        {
            PropertyInfo fi = t.GetProperty(fieldName, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);

            return fi.GetValue(obj, null);
        }

        private string GetParam(Uri url,string paramName)
        {
            string paramValue = null;
            if (url.Query.Contains(paramName + "="))
            {
                string part1 = url.Query.Substring(url.Query.IndexOf(paramName + "="));

                string part2 = "";
                if (part1.Contains("&"))
                    part2 = part1.Substring(part1.IndexOf("&"));
                string part0;

                part0 = part1.Replace(part2, "");
                paramValue = part0.Replace(paramName + "=", "");
                Console.WriteLine("param " + paramName + " = " + paramValue);
            }
            return paramValue;
        }
        /// <summary>
        /// Retourne la vue de la list en cours
        /// </summary>
        /// <param name="oParent"></param>
        /// <returns></returns>
        protected ListViewWebPart FindListView(Control oParent)
        {
            if (oParent is ListViewWebPart)
                return (ListViewWebPart)oParent;

            if (oParent.Parent == null)
                return null;

            return FindListView(oParent.Parent);
        }
    }
}